<template>
    <div class="slider-row v-ui">
        <div class="v-ui-area">
            <div class="track">
                <div class="bar-wrap">
                    <div class="bar" :style="`transform: scaleX(${barScaleX});`"></div>
                </div>
                <div class="thumb" :style="`transform: translateX(${thumbOffsetX}px);`">
                    <div class="thumb-dot"></div>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref, watch, onMounted, nextTick } from 'vue'

const emit = defineEmits(["update:order"], ["changeCurrent"]);

const props = defineProps({
    currentPer: {
        type: Number,
        default: 0 // 默认值 0
    },
    sliderWidth: {
        type: Number,
        default: 12 // 默认宽度 12
    },
    order: {
        type: Boolean,
        default: false // 默认值 false
    }
})

const isDragging = ref(false) // 是否正在拖动
const barScaleX = ref(0) // 滑动条的进度比例
const thumbOffsetX = ref(0) // 滑块的偏移量

// 引用滑块容器元素
const slider = ref(null)

// 初始化滑块位置
const initPosition = () => {
    barScaleX.value = props.currentPer // 设置滑动条的比例
    thumbOffsetX.value = (props.sliderWidth - 12) * props.currentPer // 设置滑块的偏移量
    emit('update:order', false) // 更新 order 状态
}

// 拖动初始化逻辑
const initDrag = (e) => {
    let offsetX, currPer // 当前进度比例

    // 处理鼠标按下事件
    if (e.type === 'mousedown') {
        document.addEventListener("mousemove", handleMouseMove)
        document.addEventListener("mouseup", handleMouseUp)
    } else if (e.type === 'touchstart') {
        // 处理触摸开始事件
        document.addEventListener("touchmove", handleTouchMove, { passive: false })
        document.addEventListener("touchend", handleTouchEnd)
    }

    isDragging.value = true // 设置拖动状态为 true
    const sliderRect = slider.value.getBoundingClientRect() // 获取滑块的 DOM 坐标
    offsetX = (e.clientX || e.touches[0].clientX) - sliderRect.left // 计算鼠标或触摸位置的偏移量
    currPer = offsetX / sliderRect.width // 计算进度比例
    barScaleX.value = currPer // 更新滑动条的进度比例
    thumbOffsetX.value = (sliderRect.width - 12) * currPer // 更新滑块的偏移量
    emit("changeCurrent", currPer) // 触发事件，传递当前进度比例
}

// 处理鼠标移动事件
const handleMouseMove = (e) => {
    if (!isDragging.value) return // 如果没有在拖动，则不处理
    const sliderRect = slider.value.getBoundingClientRect() // 获取滑块的 DOM 坐标
    let offsetX = e.clientX - sliderRect.left // 计算鼠标偏移量
    let currPer = offsetX / sliderRect.width // 计算进度比例
    currPer = Math.max(0, Math.min(1, currPer)) // 限制进度比例在 0~1 之间
    barScaleX.value = currPer // 更新滑动条进度比例
    thumbOffsetX.value = (sliderRect.width - 12) * currPer // 更新滑块的偏移量
    emit("changeCurrent", currPer) // 触发事件，传递当前进度比例
}

// 处理鼠标释放事件
const handleMouseUp = () => {
    isDragging.value = false // 设置拖动状态为 false
    document.removeEventListener("mousemove", handleMouseMove)
    document.removeEventListener("mouseup", handleMouseUp)
}

// 处理触摸移动事件
const handleTouchMove = (e) => {
    if (!isDragging.value) return // 如果没有在拖动，则不处理
    const sliderRect = slider.value.getBoundingClientRect() // 获取滑块的 DOM 坐标
    let offsetX = e.touches[0].clientX - sliderRect.left // 计算触摸偏移量
    let currPer = offsetX / sliderRect.width // 计算进度比例
    currPer = Math.max(0, Math.min(1, currPer)) // 限制进度比例在 0~1 之间
    barScaleX.value = currPer // 更新滑动条进度比例
    thumbOffsetX.value = (sliderRect.width - 12) * currPer // 更新滑块的偏移量
    emit("changeCurrent", currPer) // 触发事件，传递当前进度比例
}

// 处理触摸释放事件
const handleTouchEnd = () => {
    isDragging.value = false // 设置拖动状态为 false
    document.removeEventListener("touchmove", handleTouchMove)
    document.removeEventListener("touchend", handleTouchEnd)
}

// 监听 order prop 的变化，重新初始化滑块位置
watch(() => props.order, (curr) => {
    if (curr) {
        initPosition() // 如果 order 发生变化，重新初始化滑块位置
    }
})

// 在组件挂载完成后初始化滑块位置
onMounted(() => {
    nextTick(() => {
        initPosition() // 等待 DOM 更新后调用初始化
    })
})
</script>

<style scoped>
.slider-row {
    cursor: pointer;
    width: 12px;
}

.track {
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    height: 2px;
    position: relative;
    width: 100%;
}

.bar-wrap {
    background: #e7e7e7;
    border-radius: 1.5px;
    bottom: 0;
    left: 0;
    overflow: hidden;
    position: absolute;
    right: 0;
    top: 0;
}

.bar {
    background: var(--brand_pink);
    bottom: 0;
    left: 0;
    position: absolute;
    right: 0;
    top: 0;
    -webkit-transform-origin: 0 100%;
    transform-origin: 0 100%;
}

.thumb {
    bottom: 0;
    position: relative;
    top: auto;
    cursor: pointer;
    left: 0;
}

.thumb-dot {
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    background-color: var(--brand_pink);
    border-radius: 50%;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
    -webkit-transition: all .2s;
    transition: all .2s;
    vertical-align: middle;
    height: 12px;
    width: 12px;
}
</style>